﻿using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Sgr.Oss;
using Sgr.Oss.Services;
using Sgr.Utilities;
using System;
using System.IO;

namespace Microsoft.Extensions.DependencyInjection
{
    /// <summary>
    /// 提供用于注册和配置本地OSS存储服务的扩展方法
    /// </summary>
    public static class ServiceCollectionExtensions
    {
        /// <summary>
        /// 注册并配置本地OSS存储服务
        /// </summary>
        /// <param name="services">服务集合</param>
        /// <param name="configureOptions">配置选项</param>
        /// <returns>服务集合</returns>
        public static IServiceCollection AddLocalFilesystemOssService(
            this IServiceCollection services,
            Action<LocalFilesystemOptions>? configureOptions = null)
        {
            // 1. 配置验证器
            services.AddOptions<LocalFilesystemOptions>()
                 .BindConfiguration("Sgr:Oss:LocalFilesystemOptions")
                 .Validate(ValidateOptionsInternal, "Invalid LocalFilesystemOptions configuration");

            // 2. 用户自定义配置
            if (configureOptions != null)
                services.Configure(configureOptions);

            // 3. 后配置（设置默认值）
            services.PostConfigure<LocalFilesystemOptions>(options =>
            {
                ConfigureDefaults(options);

                ValidateOptions(options); // 最终验证
            });

            // 5. 注册服务
            services.TryAddSingleton<IOssService, LocalFilesystemOssService>();

            return services;
        }

        /// <summary>
        /// 验证所有配置项
        /// </summary>
        private static void ValidateOptions(LocalFilesystemOptions options)
        {
            // WorkDir 验证
            if (string.IsNullOrWhiteSpace(options.WorkDir))
                throw new ArgumentException("WorkDir cannot be empty", nameof(options));
            if (options.WorkDir.Length > 260)
                throw new ArgumentException("WorkDir path length cannot exceed 260 characters", nameof(options));

            // BaseUrl 验证
            if (!string.IsNullOrEmpty(options.BaseUrl) && !Uri.TryCreate(options.BaseUrl, UriKind.Absolute, out _))
                throw new ArgumentException("BaseUrl must be a valid absolute URL", nameof(options));

            // SignKey 验证
            if (string.IsNullOrWhiteSpace(options.SignKey))
                throw new ArgumentException("SignKey cannot be empty", nameof(options));
            if (options.SignKey.Length < 8)
                throw new ArgumentException("SignKey length must be at least 8 characters", nameof(options));

            // 分区数量验证
            if (options.BucketPartitionCount < 1 || options.BucketPartitionCount > 999)
                throw new ArgumentException("BucketPartitionCount must be between 1 and 999", nameof(options));
            if (options.ObjectPartitionCount < 1 || options.ObjectPartitionCount > 999)
                throw new ArgumentException("ObjectPartitionCount must be between 1 and 999", nameof(options));

            // 目录文件数量验证
            if (options.MaxFilesPerDirectory < 1 || options.MaxFilesPerDirectory > 100000)
                throw new ArgumentException("MaxFilesPerDirectory must be between 1 and 100000", nameof(options));
        }

        /// <summary>
        /// 内部验证方法，用于Options验证器
        /// </summary>
        private static bool ValidateOptionsInternal(LocalFilesystemOptions options)
        {
            try
            {
                ValidateOptions(options);
                return true;
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// 配置默认值
        /// </summary>
        private static void ConfigureDefaults(LocalFilesystemOptions options)
        {
            // BaseUrl 处理
            if (string.IsNullOrWhiteSpace(options.BaseUrl))
            {
                options.BaseUrl = GetDefaultBaseUrl();
            }

            // SignKey 处理
            if (string.IsNullOrWhiteSpace(options.SignKey))
            {
                options.SignKey = Guid.NewGuid().ToString("N");
            }

            // 确保其他默认值
            options.WorkDir = string.IsNullOrWhiteSpace(options.WorkDir) ? "oss_data" : options.WorkDir;
        }

        /// <summary>
        /// 获取默认的BaseUrl
        /// </summary>
        private static string GetDefaultBaseUrl()
        {
            var baseUrl = EnvironmentHelper.GetEnvironmentVariable("ASPNETCORE_URLS");
            if (!string.IsNullOrEmpty(baseUrl))
            {
                var urls = baseUrl.Split(';', StringSplitOptions.RemoveEmptyEntries);
                if (urls.Length > 0)
                {
                    var url = urls[0].TrimEnd('/');
                    if (Uri.TryCreate(url, UriKind.Absolute, out _))
                    {
                        return url;
                    }
                }
            }
            return string.Empty;
        }
    }
}